﻿using System;
using System.Linq;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Samurai.Wakizashi.Caching;

// ReSharper disable InconsistentNaming
namespace Samurai.Caching.Tests
{
    [TestClass]
    public class ExpiringKeyCache_Tests
    {
        private bool _actionExecuted;

        [TestMethod]
        public void Provides_an_enumerable_collection_of_all_items_in_the_cache()
        {
            var cache = new ExpiringKeyedCache(TimeSpan.FromMilliseconds(500));
            cache.CacheItem("xxx", new CacheItem());

            Assert.IsTrue(cache.AllItems.Count() == 1);
        }

        [TestMethod]
        public void Caches_items()
        {
            var cache = new ExpiringKeyedCache(TimeSpan.FromMilliseconds(500));
            cache.CacheItem("xxx", new CacheItem());

            Assert.IsTrue(cache.AllItems.Count() == 1);
        }

        [TestMethod]
        public void Evicts_specified_item_from_cache()
        {
            var cacheItem = new CacheItem { Prop1 = "xxx" };
            var cache = new ExpiringKeyedCache(TimeSpan.FromMilliseconds(500));
            cache.CacheItem("xxx", cacheItem);
            cache.EvictItem("xxx");

            Assert.IsTrue(cache.AllItems.Count() == 0);
        }

        [TestMethod]
        public void Clears_all_items_from_cache()
        {
            var cacheItem = new CacheItem { Prop1 = "xxx" };
            var cacheItem2 = new CacheItem { Prop1 = "zxzz" };
            var cache = new ExpiringKeyedCache(TimeSpan.FromMilliseconds(500));
            cache.CacheItem("xxx", cacheItem);
            cache.CacheItem("yyy", cacheItem2);
            cache.Clear();

            Assert.IsTrue(cache.AllItems.Count() == 0);
        }

        [TestMethod]
        public void Evicts_cache_at_designated_expiration_period()
        {
            var cache = new ExpiringKeyedCache(TimeSpan.FromMilliseconds(500));

            cache.CacheItem("xxx", new CacheItem());

            Thread.Sleep(800);

            Assert.IsTrue(cache.AllItems.Count() == 0);
        }

        [TestMethod]
        public void Executes_specified_action_at_designated_expiration_period()
        {
            var cache = new ExpiringKeyedCache(TimeSpan.FromMilliseconds(500))
            {
                ExpireAction = ExpirationAction
            };

            // Expiration timer will not begin until we add the first item
            cache.CacheItem("xxx", new CacheItem());

            Thread.Sleep(800);

            Assert.IsTrue(_actionExecuted);
        }

        private void ExpirationAction(IExpiringCacheStore cache)
        {
            _actionExecuted = true;
        }
    }
}
// ReSharper restore InconsistentNaming